package com.ruubypay.biz.utils.file;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 文件下载
 * @author chenhaiyang
 */
public class FileDownload {

    private static Logger logger = LoggerFactory.getLogger(FileDownload.class);

    /**
     * 文件下载到浏览器输出流
     * @param response 响应
     * @param filePath 文件完整路径(包括文件名和扩展名)
     * @param fileName	下载后看到的文件名
     */
    public static void fileDownload(final HttpServletResponse response, String filePath, String fileName) throws Exception{
        byte[] data = toByteArray(filePath);
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream;charset=UTF-8");
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        outputStream.write(data);
        outputStream.flush();
        outputStream.close();
        response.flushBuffer();
    }

    /**
     * 读取到字节数组
     *
     * @param filePath 文件路径
     * @throws IOException  IO异常
     */
    private static byte[] toByteArray(String filePath) throws IOException {
        File f = new File(filePath);
        if (!f.exists()) {
            throw new FileNotFoundException(filePath);
        }
        try(
                FileInputStream fs = new FileInputStream(f);
                FileChannel channel = fs.getChannel()
            ) {

            ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
            while (true) {
                if (!(channel.read(byteBuffer) > 0)){
                    break;
                }
            }
            return byteBuffer.array();
        }catch (Exception e){
            logger.error(e.getMessage(),e);
        }
        return new byte[]{};
    }
}
